home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_055 / screensave / ilbmw.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  5KB  |  145 lines

  1. /*----------------------------------------------------------------------*
  2.  * ILBMW.C  Support routines for writing ILBM files.            1/23/86
  3.  * (IFF is Interchange Format File.)
  4.  *
  5.  * By Jerry Morrison and Steve Shaw, Electronic Arts.
  6.  * This software is in the public domain.
  7.  *
  8.  * This version for the Commodore-Amiga computer.
  9.  *----------------------------------------------------------------------*/
  10. #include "iff/packer.h"
  11. #include "iff/ilbm.h"
  12.  
  13. /*---------- InitBMHdr -------------------------------------------------*/
  14. IFFP InitBMHdr(bmHdr0, bitmap, masking, compression, transparentColor,
  15.         pageWidth, pageHeight)
  16.         BitMapHeader *bmHdr0;  struct BitMap *bitmap;
  17.         WORD masking;        /* Masking */
  18.     WORD compression;    /* Compression */
  19.     WORD transparentColor;    /* UWORD */
  20.     WORD pageWidth, pageHeight;
  21.     {
  22.     register BitMapHeader *bmHdr = bmHdr0;
  23.     register WORD rowBytes = bitmap->BytesPerRow;
  24.  
  25.     bmHdr->w = rowBytes << 3;
  26.     bmHdr->h = bitmap->Rows;
  27.     bmHdr->x = bmHdr->y = 0;    /* Default position is (0,0).*/
  28.     bmHdr->nPlanes = bitmap->Depth;
  29.     bmHdr->masking = masking;
  30.     bmHdr->compression = compression;
  31.     bmHdr->pad1 = 0;
  32.     bmHdr->transparentColor = transparentColor;
  33.     bmHdr->xAspect = bmHdr->yAspect = 1;
  34.     bmHdr->pageWidth = pageWidth;
  35.     bmHdr->pageHeight = pageHeight;
  36.  
  37.     if (pageWidth = 320)
  38.     switch (pageHeight) {
  39.         case 200: {bmHdr->xAspect = x320x200Aspect;
  40.                bmHdr->yAspect = y320x200Aspect; break;}
  41.         case 400: {bmHdr->xAspect = x320x400Aspect;
  42.                bmHdr->yAspect = y320x400Aspect; break;}
  43.         }
  44.     else if (pageWidth = 640)
  45.     switch (pageHeight) {
  46.         case 200: {bmHdr->xAspect = x640x200Aspect;
  47.                bmHdr->yAspect = y640x200Aspect; break;}
  48.         case 400: {bmHdr->xAspect = x640x400Aspect;
  49.                bmHdr->yAspect = y640x400Aspect; break;}
  50.         }
  51.  
  52.     return( IS_ODD(rowBytes) ? CLIENT_ERROR : IFF_OKAY );
  53.     }
  54.  
  55. /*---------- PutCMAP ---------------------------------------------------*/
  56. IFFP PutCMAP(context, colorMap, depth)   
  57.       GroupContext *context;  WORD *colorMap;  UBYTE depth;
  58.    {
  59.    register LONG nColorRegs;   
  60.    IFFP iffp;
  61.    ColorRegister colorReg;
  62.  
  63.    if (depth > MaxAmDepth)   depth = MaxAmDepth;
  64.    nColorRegs = 1 << depth;
  65.  
  66.    iffp = PutCkHdr(context, ID_CMAP, nColorRegs * sizeofColorRegister);
  67.    CheckIFFP();
  68.  
  69.    for ( ;  nColorRegs;  --nColorRegs)  {
  70.       colorReg.red   = ( *colorMap >> 4 ) & 0xf0;
  71.       colorReg.green = ( *colorMap      ) & 0xf0;
  72.       colorReg.blue  = ( *colorMap << 4 ) & 0xf0;
  73.       iffp = IFFWriteBytes(context, (BYTE *)&colorReg, sizeofColorRegister);
  74.       CheckIFFP();
  75.       ++colorMap;
  76.       }
  77.  
  78.    iffp = PutCkEnd(context);
  79.    return(iffp);
  80.    }
  81.  
  82. /*---------- PutBODY ---------------------------------------------------*/
  83. /* NOTE: This implementation could be a LOT faster if it used more of the
  84.  * supplied buffer. It would make far fewer calls to IFFWriteBytes (and
  85.  * therefore to DOS Write). */
  86. IFFP PutBODY(context, bitmap, mask, bmHdr, buffer, bufsize)
  87.       GroupContext *context;  struct BitMap *bitmap;  BYTE *mask;
  88.       BitMapHeader *bmHdr;  BYTE *buffer;  LONG bufsize;
  89.    {         
  90.    IFFP iffp;
  91.    LONG rowBytes = bitmap->BytesPerRow;
  92.    int dstDepth = bmHdr->nPlanes;
  93.    Compression compression = bmHdr->compression;
  94.    int planeCnt;        /* number of bit planes including mask */
  95.    register int iPlane, iRow;
  96.    register LONG packedRowBytes;
  97.    BYTE *buf;
  98.    BYTE *planes[MaxAmDepth + 1]; /* array of ptrs to planes & mask */
  99.  
  100.    if ( bufsize < MaxPackedSize(rowBytes)  ||    /* Must buffer a comprsd row*/
  101.         compression > cmpByteRun1  ||        /* bad arg */
  102.     bitmap->Rows != bmHdr->h   ||        /* inconsistent */
  103.     rowBytes != RowBytes(bmHdr->w)  ||    /* inconsistent*/
  104.     bitmap->Depth < dstDepth   ||        /* inconsistent */
  105.     dstDepth > MaxAmDepth )            /* too many for this routine*/
  106.       return(CLIENT_ERROR);
  107.  
  108.    planeCnt = dstDepth + (mask == NULL ? 0 : 1);
  109.  
  110.    /* Copy the ptrs to bit & mask planes into local array "planes" */
  111.    for (iPlane = 0; iPlane < dstDepth; iPlane++)
  112.       planes[iPlane] = (BYTE *)bitmap->Planes[iPlane];
  113.    if (mask != NULL)
  114.       planes[dstDepth] = mask;
  115.  
  116.    /* Write out a BODY chunk header */
  117.    iffp = PutCkHdr(context, ID_BODY, szNotYetKnown);
  118.    CheckIFFP();
  119.  
  120.    /* Write out the BODY contents */
  121.    for (iRow = bmHdr->h; iRow > 0; iRow--)  {
  122.       for (iPlane = 0; iPlane < planeCnt; iPlane++)  {
  123.  
  124.          /* Write next row.*/
  125.          if (compression == cmpNone) {
  126.             iffp = IFFWriteBytes(context, planes[iPlane], rowBytes);
  127.             planes[iPlane] += rowBytes;
  128.             }
  129.  
  130.          /* Compress and write next row.*/
  131.          else {
  132.             buf = buffer;
  133.             packedRowBytes = PackRow(&planes[iPlane], &buf, rowBytes);
  134.             iffp = IFFWriteBytes(context, buffer, packedRowBytes);
  135.             }
  136.  
  137.          CheckIFFP();
  138.          }
  139.       }
  140.  
  141.    /* Finish the chunk */
  142.    iffp = PutCkEnd(context);
  143.    return(iffp);
  144.    }
  145.